# -*- coding: utf-8 -*-
# owner: shenyi

from typing import Optional

from src.providers.base import BaseProvider
from src.models.instance import (
    CreateInstanceRequest,
    DeleteInstanceRequest,
    InstanceTypeRequest,
    AvailableInstanceTypeRequest,
    QueryInstanceRequest
)
from src.models.responses import (
    CreateResponse,
    DeleteResponse,
    InstanceTypeResponse,
    AvailableZonesInstanceTypeResponse,
    InstanceType as ResponseInstanceType,
    InstanceListResponse
)
from src.core import logger
from src.strategies.strategy import ExcludeInstanceFamilyStrategy, CpuStrategy, MemoryStrategy

from .client import Client
from huaweicloudsdkcore.exceptions import exceptions
from huaweicloudsdkecs.v2 import *


class Ecs(BaseProvider):
    """
    华为云 ECS 实现类
    """

    def __init__(self, **config):
        super().__init__(**config)
        # 可选：将 client 作为实例属性，支持依赖注入（便于 mock 测试）
        self._client = config.get("client") or Client.ecs_client()

    async def create_instance(self, request: CreateInstanceRequest) -> CreateResponse:
        """
        创建云服务器(按需)

        Docs： https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/sdk?api=CreatePostPaidServers
        """

        try:
            # 标签
            server_tags = []
            if request.tag:
                for tag in request.tag:
                    server_tags.append(PostPaidServerTag(tag["key"], tag["value"]))

            # 加载数据盘
            data_volumes = []
            if request.data_disk:
                for d in request.data_disk:
                    size = d["size"]
                    data_volumes.append(PostPaidServerDataVolume(
                        volumetype=d["category"].upper(), 
                        size=size
                    ))

            # 公网选项
            publicip_server = None
            if request.internet_max_bandwidth_out > 0:
                bandwidth_eip = PostPaidServerEipBandwidth(
                    size=request.internet_max_bandwidth_out,
                    sharetype="PER"
                )
                eip_publicip = PostPaidServerEip(
                    iptype="5_bgp",
                    bandwidth=bandwidth_eip
                )
                publicip_server = PostPaidServerPublicip(
                    eip=eip_publicip
                )

            server_body = PostPaidServer(
                flavor_ref=request.instance_type,
                image_ref=request.image_id,
                name=request.host_name,
                vpcid=request.vpc_id,
                key_name=None if request.password_inherit else request.key_pair_name,
                nics=[PostPaidServerNic(subnet_id=request.subnet_id)],
                root_volume=PostPaidServerRootVolume(volumetype="ESSD"),
                data_volumes=data_volumes,
                security_groups=[PostPaidServerSecurityGroup(request.security_group_id)],
                server_tags=server_tags,
                publicip=publicip_server
            )
            
            req = CreatePostPaidServersRequest()
            req.body = CreatePostPaidServersRequestBody(server=server_body)
            response = self._client.create_post_paid_servers(req)

            instance_ids = response.server_ids or []
            return CreateResponse(instance_ids=instance_ids)
        except Exception as e:
            error_msg = str(e)
            logger.error(f"Failed to create ECS instance: {error_msg}")
            return CreateResponse(status_code=400, message=error_msg)

    async def delete_instance(self, request: DeleteInstanceRequest) -> DeleteResponse:
        """
        删除云实例
        Docs https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/sdk?api=DeleteServers
        """

        try:
            req = DeleteServersRequest()
            servers_body = [
                ServerId(id=request.instance_id)
            ]
            req.body = DeleteServersRequestBody(
                servers=servers_body,
                delete_volume=True,
                delete_publicip=True
            )
            self._client.delete_servers(req)
            return DeleteResponse(status_code=200, message="success")
        except exceptions.ClientRequestException as e:
            logger.error(f"Failed to delete ECS instance {request.instance_id}: {e.error_msg}")
            return DeleteResponse(status_code=e.status_code, message=e.error_msg)
        except Exception as e:
            error_msg = str(e)
            logger.error(f"Failed to delete ECS instance {request.instance_id}: {error_msg}")
            return DeleteResponse(status_code=400, message=error_msg)

    async def list_instance_types(self, request: InstanceTypeRequest) -> InstanceTypeResponse:
        """
        获取ECS规格实例

        Docs: https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/doc?api=ListFlavors
        """

        try:
            req = ListFlavorsRequest()
            response = self._client.list_flavors(req)
            flavors = response.flavors or []
            
            filtered_specs = []
            for flavor in flavors:
                # az content: "cond:operation:az":"cn-east-3a(normal),cn-east-3b(abandon)
                az = flavor.os_extra_specs.condoperationaz
                if az:
                    if "normal" in az or "promotion" in az:
                        status = "normal"
                    else:
                        status = "abandon"
                else:
                    status = flavor.os_extra_specs.condoperationstatus

                if status in ["abandon", "sellout", "obt"]:
                    continue

                # 过滤cpu分类
                instance_category = flavor.os_extra_specs.ecsperformancetype
                if request.instance_category and instance_category != request.instance_category:
                    continue

                # 过滤cpu架构 ecsinstance_architecture:该规格对应的CPU架构,且仅鲲鹏实例架构规格返回该字段 取值为arm64表示CPU架构为鲲鹏计算。
                architecture = flavor.os_extra_specs.ecsinstance_architecture
                cpu_architecture = architecture if architecture else request.cpu_architecture.lower()
                if request.cpu_architecture.lower() not in cpu_architecture:
                    continue

                # 判断大小
                ram_size = flavor.ram / 1024
                if CpuStrategy.filter(int(flavor.vcpus), request.mini_cpu_count) or \
                   MemoryStrategy.filter(ram_size, request.mini_memory_size):
                    continue

                # 应用排除族策略
                if request.exclude_families and ExcludeInstanceFamilyStrategy.exclude(
                    flavor.id, request.exclude_families
                ):
                    continue

                filtered_specs.append(ResponseInstanceType(
                    instance_type_id=flavor.id,
                    cpu_core_count=flavor.vcpus,
                    memory_size=ram_size,
                    cpu_architecture=cpu_architecture if cpu_architecture else "x86"
                ))

            return InstanceTypeResponse(
                status_code=200,
                message="success",
                instance_spec=filtered_specs
            )
        except exceptions.ClientRequestException as e:
            logger.error(f"Failed to list ECS instance types: {e.error_msg}")
            return InstanceTypeResponse(
                status_code=e.status_code, 
                message=e.error_msg, 
                instance_spec=[]
            )
        except Exception as e:
            error_msg = str(e)
            logger.error(f"Failed to list ECS instance types: {error_msg}")
            return InstanceTypeResponse(
                status_code=400, 
                message=error_msg, 
                instance_spec=[]
            )

    async def list_available_instance_types(self, request: AvailableInstanceTypeRequest) -> AvailableZonesInstanceTypeResponse:
        """
        获取可用的云实例规格
        Docs https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/sdk?api=ListFlavors
        """
        # 这里可以实现获取可用实例类型的逻辑
        return AvailableZonesInstanceTypeResponse(
            status_code=200, 
            message="success", 
            instance_spec=[]
        )
        
    async def list_instances(self, request: QueryInstanceRequest) -> InstanceListResponse:
        """
        获取ECS实例列表

        Docs: https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/sdk?api=ListServersDetails
        """
        return InstanceListResponse(
            status_code=200, 
            message="success", 
            instance_list=[]
        )